package com.plan.schedule;

import com.plan.base.util.DateUtil;
import com.plan.dao.mapper.card.DayPlanStatMapper;
import com.plan.dao.mapper.card.ExchangeLogMapper;
import com.plan.dao.service.card.CardDaoService;
import com.plan.dao.service.card.DayPlanDaoService;
import com.plan.dao.service.card.PointLogDaoService;
import com.plan.entity.card.Card;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 定时真正物理删除积分卡相关数据
 *
 * @author zcl
 */
@Slf4j
@Component
public class RealDeleteCardSchedule {
    @Resource
    private CardDaoService cardDaoService;
    @Resource
    private DayPlanDaoService dayPlanDaoService;
    @Resource
    private DayPlanStatMapper dayPlanStatMapper;
    @Resource
    private ExchangeLogMapper exchangeLogMapper;
    @Resource
    private PointLogDaoService pointLogDaoService;


    @Scheduled(cron = "0 0 1 * * ?")
    public void realDeleteCard() {
        log.info("realDeleteCard start");
        // 找到更新时间是30天之前的，且状态是删除标识的 积分卡，然后删除它及其相关的数据
        Date now = new Date();
        // 冗余10天，40天之前的不处理了，时间跨度太大
        Date start = DateUtil.addDays(now, -40);
        Date end = DateUtil.addDays(now, -30);
        Long preMaxId = 0L;
        while (true) {
            try {
                List<Card> list = cardDaoService.selectWaitDeleteCard(start, end, preMaxId);
                if (CollectionUtils.isEmpty(list)) {
                    return;
                }
                preMaxId = list.get(list.size() - 1).getId();
                this.del(list);
            } catch (Exception e) {
                log.error("realDeleteCard error", e);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }

    }

    private void del(List<Card> list) {
        // card本身要放在最后删除，其它数据即使不再同一事务删除可以
        for (Card card : list) {
            dayPlanDaoService.realDeleteByCardId(card.getTeamId(), card.getId());
            dayPlanStatMapper.realDeleteByCardId(card.getTeamId(), card.getId());
            exchangeLogMapper.realDeleteByCardId(card.getTeamId(), card.getId());
            // todo 这一个删除后面要做成分批次删除
            pointLogDaoService.realDeleteByCardId(card.getTeamId(), card.getId());
            cardDaoService.realDeleteByCardId(card.getTeamId(), card.getId());
        }
    }

}
